package com.ziyun.erp.modules.production.operate;

import com.cloud.bus.core.EventBusPusher;
import com.cloud.bus.event.order.OrderMessageEvent;
import com.utility.DateUtils;
import com.ziyun.erp.common.e.logistics.LogisticsSendTypeEnum;
import com.ziyun.erp.common.e.order.*;
import com.ziyun.erp.common.e.production.FinanceStatusEnum;
import com.ziyun.erp.common.e.production.OrderProductionStatusEnum;
import com.ziyun.erp.modules.logistics.dto.ErpLogisticsDto;
import com.ziyun.erp.modules.logistics.entity.ErpLogisticsEntity;
import com.ziyun.erp.modules.logistics.entity.ErpLogisticsItemEntity;
import com.ziyun.erp.modules.logistics.service.ErpLogisticsItemService;
import com.ziyun.erp.modules.logistics.service.ErpLogisticsService;
import com.ziyun.erp.modules.order.entity.ErpOrderAllotRelevanceEntity;
import com.ziyun.erp.modules.order.entity.ErpOrderLogEntity;
import com.ziyun.erp.modules.order.entity.OrderInfoEntity;
import com.ziyun.erp.modules.order.service.ErpOrderAllotRelevanceService;
import com.ziyun.erp.modules.order.service.ErpOrderLogService;
import com.ziyun.erp.modules.order.service.ErpOrderService;
import com.ziyun.erp.modules.order.service.OrderInfoService;
import com.ziyun.erp.modules.production.entity.ErpOrderProductionEntity;
import com.ziyun.erp.modules.production.operate.entity.AllotStateEntity;
import com.ziyun.erp.modules.production.operate.entity.AuditStateEntity;
import com.ziyun.erp.modules.production.operate.entity.LogisticsStateEntity;
import com.ziyun.erp.modules.production.service.ErpOrderItemService;
import com.ziyun.erp.modules.production.service.ErpOrderProductionService;
import io.renren.common.utils.R;
import io.renren.common.utils.SpringContextUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author guizhao
 * @Title: 生产完成状态
 * @ProjectName ziyun-service-erp
 * @date 2018-09-08 15:57
 */
public class ProduceFinishState implements ErpOrderState {

    private static Logger logger = LoggerFactory.getLogger(ProduceFinishState.class);

    private ErpOrderProductionService erpOrderProductionService = SpringContextUtils.getBean("erpOrderProductionService", ErpOrderProductionService.class);
    private ErpOrderAllotRelevanceService relevanceService = SpringContextUtils.getBean("erpOrderAllotRelevanceService", ErpOrderAllotRelevanceService.class);
    private OrderInfoService orderInfoService = SpringContextUtils.getBean("orderInfoService", OrderInfoService.class);
    private ErpOrderService erpOrderService = SpringContextUtils.getBean("erpOrderService", ErpOrderService.class);
    private ErpOrderLogService erpOrderLogService = SpringContextUtils.getBean("erpOrderLogService", ErpOrderLogService.class);
    private ErpOrderItemService erpOrderItemService = SpringContextUtils.getBean("erpOrderItemService", ErpOrderItemService.class);
    private ErpLogisticsService erpLogisticsService = SpringContextUtils.getBean("erpLogisticsService", ErpLogisticsService.class);
    private ErpLogisticsItemService erpLogisticsItemService = SpringContextUtils.getBean("erpLogisticsItemService", ErpLogisticsItemService.class);

    @Override
    public R audit(AuditStateEntity auditStateEntity) {
        return R.error("不支持操作！");
    }

    @Override
    public R allot(AllotStateEntity allotStateEntity) {
        return R.error("不支持操作！");
    }

    @Override
    public R receive(Integer productionId) {
        return R.error("不支持操作！");
    }

    @Override
    public R addLogistics(LogisticsStateEntity logisticsStateEntity, String userId, String createName ) {
        logger.info("=================order addLogistics start================");
        logger.info("=================order addLogistics params：" + logisticsStateEntity.toString());

        ErpLogisticsDto erpLogisticsDto = logisticsStateEntity.getErpLogisticsDto();
        ErpLogisticsEntity erpLogistics = erpLogisticsDto.getErpLogisticsEntity();
        String orderNo = erpLogistics.getOrderNo();
        // 添加物流信息
        Date currDate = new Date();
        erpLogistics.setCreateName(createName);
        erpLogistics.setSendTime(currDate);
        erpLogisticsService.insert(erpLogistics);
        OrderInfoEntity orderInfo = orderInfoService.selectById(orderNo);
        if (orderInfo != null){
            // 线上订单
            List<ErpLogisticsItemEntity> erpLogisticsItemList = erpLogisticsDto.getErpLogisticsItemList();
            int itemListSize = erpLogisticsItemList.size();
            if(itemListSize > 0 ){
                erpLogisticsItemService.saveBatchByLogisticsId(erpLogisticsItemList, erpLogistics.getLogiId());
            }
            int sendType = erpLogistics.getSendType();
            int logiType = erpLogistics.getLogiType();
            if (sendType == LogisticsSendTypeEnum.ORDER.toInt()){
                if (itemListSize > 0){
                    // 商品状态 生产完成 =》 已发货
                    List<Integer> itemIds = erpLogisticsItemList.stream().map(ErpLogisticsItemEntity::getOrderItemId).collect(Collectors.toList());
                    Map<String, Object> updateMap = new HashMap<>();
                    updateMap.put("status", OrderItemStatusEnum.DELIVERED.toInt());
                    erpOrderItemService.updateBatchByOrderItemId(updateMap, itemIds);
                }
                // 订单状态 生产完成 =》 已发货
                erpOrderProductionService.erpOrderItemAddLogistics(orderInfo, logiType);
            }else {
                // 发票、样品（只做记录，不影响订单发货状态）
            }

            // 发送订单发货事件
            OrderMessageEvent event = new OrderMessageEvent(this, Long.valueOf(orderInfo.getUserId()), orderNo, "delivery");
            EventBusPusher.syncPost(event);
        }

        ErpOrderLogEntity erpOrderLog = new ErpOrderLogEntity();
        erpOrderLog.setOrderNo(orderNo);
        erpOrderLog.setCreateBy(userId);
        erpOrderLog.setCreateName(createName);
        erpOrderLog.setLogText("添加物流，logiId：" + erpLogistics.getLogiId());
        erpOrderLogService.insert(erpOrderLog);

        logger.info("=================order addLogistics end==================");
        return R.ok();
    }

    @Override
    public R allotPriceFinish(Integer productionId) {
        logger.info("=================order allotPriceFinish start================");
        logger.info("=================order allotPriceFinish params：productionId["+ productionId +"]");

        ErpOrderProductionEntity erpOrderProduction = erpOrderProductionService.selectById(productionId);
        if (erpOrderProduction.getProductionStatus().intValue() != OrderProductionStatusEnum.FINISH.toInt()){
            return R.error("生产单状态异常！");
        }
        if (erpOrderProduction.getFinanceStatus().intValue() != FinanceStatusEnum.UN_AUDITED.toInt()){
            return R.error("生产单审核状态异常！");
        }

        ErpOrderAllotRelevanceEntity relevanceEntity =  relevanceService.getByProductionId(productionId);
        String originalOrderNo = relevanceEntity.getOriginalOrderNo();
        String orderAllotNo = relevanceEntity.getOrderAllotNo();
        OrderInfoEntity orderInfo = orderInfoService.selectById(orderAllotNo);
        BigDecimal payableAmount = orderInfo.getPayableAmount();
        String currTime = DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");

        // 原始订单财务审核状态 待审核 =》 待付款
        Map<String, Object> updateMap = new HashMap<>();
        updateMap.put("financeStatus", FinanceStatusEnum.UN_PAYD.toInt());
        updateMap.put("cost", payableAmount);
        erpOrderProductionService.updateByMap(updateMap, productionId);

        // 分配订单 状态改为已完结，确认收货时间
        updateMap.clear();
        updateMap.put("status", OrderInfoStatusEnum.FINISH.toCode());
        updateMap.put("receivedStatus", 1);
        updateMap.put("receivedTime", currTime);
        updateMap.put("payStatus", PayStatusEnum.ALREADY_PAY_1.toCode());
        updateMap.put("payed", payableAmount);
        updateMap.put("paymentTime", currTime);
        updateMap.put("payment", "月结"); // 第三方工厂月结
        orderInfoService.updateByMap(updateMap, orderAllotNo);

        updateMap.remove("status");
        updateMap.put("productionStatus", ProductionStatusEnum.FINISH.toInt());
        erpOrderService.updateByMap(updateMap, orderAllotNo);

        erpOrderLogService.insertOrderLog(originalOrderNo, "生产单审核完成，productionId：" + productionId);

        logger.info("=================order allotPriceFinish end==================");
        return R.ok();
    }

    @Override
    public R cancleAllot(Integer productionId) {
        return R.error("不支持操作！");
    }

}
